package cn.iocoder.yudao.module.trade.service.order.handler;

import cn.iocoder.yudao.framework.common.enums.trade.TradeOrderStatusEnum;
import cn.iocoder.yudao.framework.common.enums.trade.TransactionTypeEnum;
import cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil;
import cn.iocoder.yudao.module.member.api.config.dto.MemberConfMaterialDTO;
import cn.iocoder.yudao.module.member.api.config.dto.MemberConfRespDTO;
import cn.iocoder.yudao.module.pay.api.order.dto.PayOrderCreateReqDTO;
import cn.iocoder.yudao.module.pay.api.order.dto.PayOrderRespDTO;
import cn.iocoder.yudao.module.pay.enums.notify.PayNotifyTypeEnum;
import cn.iocoder.yudao.module.trade.controller.app.order.vo.AppTradeOrderOrderCreateReqVO;
import cn.iocoder.yudao.module.trade.controller.app.order.vo.AppTradeOrderOrderReqVO;
import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderDO;
import cn.iocoder.yudao.module.trade.enums.delivery.DeliveryTypeEnum;
import cn.iocoder.yudao.module.trade.service.price.bo.TradePriceCalculateReqBO;
import cn.iocoder.yudao.module.trade.service.price.bo.TradePriceCalculateRespBO;
import org.springframework.stereotype.Component;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.Objects;

import static cn.iocoder.yudao.module.trade.enums.ErrorCodeConstants.ORDER_CREATE_FAIL_USER_NO_PERMISSION;

/**
 * 旧料兑换交易模式处理器
 */
@Component
public class ExchangeMaterialTransactionHandler extends AbstractTransactionModeHandler {
    private static final TransactionTypeEnum TRANSACTION_TYPE = TransactionTypeEnum.EXCHANGE_METAL;

    @Override
    public Integer getTransactionType() {
        return TRANSACTION_TYPE.getType();
    }

    @Override
    public void validatePermission(MemberConfRespDTO memberConf) {
        if (Boolean.FALSE.equals(memberConf.getFullPayBuy())) {
            throw ServiceExceptionUtil.exception(ORDER_CREATE_FAIL_USER_NO_PERMISSION, TRANSACTION_TYPE.getDesc());
        }
    }
    
    @Override
    public void validateTradeLimits(MemberConfMaterialDTO materialConf, AppTradeOrderOrderReqVO settlementReqVO) {
        // 调用父类的通用限制校验
        super.validateTradeLimits(materialConf, settlementReqVO);
        
        // 旧料兑换特有限制校验
//        // 例如验证兑换比例、兑换资格等
//        if (materialConf.getExchangeRatio() != null &&
//            (settlementReqVO.getExchangeRatio() == null ||
//             settlementReqVO.getExchangeRatio().compareTo(materialConf.getExchangeRatio()) > 0)) {
//            throw ServiceExceptionUtil.exception(ORDER_CREATE_FAIL_EXCHANGE_RATIO_EXCEED);
//        }
//
//        // 验证可兑换的品类
//        if (materialConf.getExchangeableTypes() != null &&
//            !materialConf.getExchangeableTypes().contains(settlementReqVO.getTargetMetalType())) {
//            throw ServiceExceptionUtil.exception(ORDER_CREATE_FAIL_METAL_TYPE_NOT_EXCHANGEABLE);
//        }
    }

    @Override
    protected void setPriceResult(TradePriceCalculateReqBO calculateReqBO, TradePriceCalculateRespBO result, TradePriceCalculateRespBO context) {
        result.setPayType(PayNotifyTypeEnum.ORDER.getType());
    }

    @Override
    protected BigDecimal calculatePayPrice(TradePriceCalculateReqBO calculateReqBO, TradePriceCalculateRespBO calContext) {
        return BigDecimal.ZERO;
    }


    @Override
    public void setupDeliveryInfo(TradeOrderDO order, Long userId, AppTradeOrderOrderCreateReqVO createReqVO) {
        order.setDeliveryType(createReqVO.getDeliveryType());
        // 快递配送
        if (Objects.equals(createReqVO.getDeliveryType(), DeliveryTypeEnum.EXPRESS.getType())) {
            if (!createReqVO.getIsStore()) {
                super.createMemberAddr(userId, createReqVO.getAddressId(), order.getOrderNo(), createReqVO.getDeliveryType());
            }
            super.createStoreAddr(order, createReqVO.getPickUpStoreId(), order.getOrderNo(), DeliveryTypeEnum.EXPRESS_TO_SHOP, createReqVO.getPickupInfoId());
        } else if (Objects.equals(createReqVO.getDeliveryType(), DeliveryTypeEnum.PICK_UP.getType())) {
            super.createStoreAddr(order, createReqVO.getPickUpStoreId(), order.getOrderNo(), DeliveryTypeEnum.PICK_UP, createReqVO.getPickupInfoId());
        }

    }

    /**
     * 总额、定金、延期费？、工费、附加费=成色不足
     */
    @Override
    public PayOrderCreateReqDTO creatSettlePay(TradeOrderDO order, Boolean isViolate) {
        PayOrderCreateReqDTO payOrder = super.initPayOrderCreate(order.getOrderNo());
        // 已支付单
        PayOrderRespDTO payOrderRespDTO = payOrderApi.getOrder(order.getPayOrderId());
        // 现价
        BigDecimal livePriceBuy = livePriceApi.getConfPrice(order.getMetalType(), false);
        BigDecimal livePriceSell = livePriceApi.getConfPrice(order.getMetalType(), true);

        // 1.定金 : 要退
        BigDecimal depositFee = BigDecimal.ZERO.subtract(payOrderRespDTO.getDeposit());

        // 2. 延期配置为 0
        // 旧料兑换无延期费
        BigDecimal delayFee = BigDecimal.ZERO;
//                super.calculateDelayPrice(order.getCreateTime(), order.getInterestFreeDays(), payOrderRespDTO.getDelayPrice(), order.getDelayFeeConf());

        // 3.工费 = （克重 * 工费配置） - 已交工费
        BigDecimal processFee = super.calculateProducePrice(order.getExchangeWeight(), order.getProcessConf(), payOrderRespDTO.getProcessPrice());

        // 4.附加费 = 附加费 - 已交附加费
        BigDecimal deductPrice = order.getDeductPrice();
        //  检验结果单、需要成色 按售价
        BigDecimal additionalFee;
        BigDecimal addWeight = order.getWeight().subtract(order.getConvertWeight());
        int a = addWeight.compareTo(BigDecimal.ZERO);
        if (a == 0) {
            additionalFee = BigDecimal.ZERO;
        } else if (a > 0){
            // 少的补钱
            additionalFee = addWeight.multiply(livePriceSell);
        } else {
            // 多的回收
            additionalFee = addWeight.multiply(livePriceBuy);
        }
        additionalFee = additionalFee.subtract(payOrderRespDTO.getAdditionalPrice()).setScale(2, RoundingMode.HALF_UP).add(deductPrice);

        payOrder.setOrderNo(order.getOrderNo());
        payOrder.setDeposit(depositFee);
        payOrder.setDelayPrice(delayFee);
        payOrder.setProcessPrice(processFee);
        payOrder.setAdditionalPrice(additionalFee);
        payOrder.setPrice(delayFee.add(processFee).add(additionalFee));
        return payOrder;
    }

    @Override
    public TradeOrderStatusEnum getNextStatusBySuceess(TradeOrderDO order, Integer payType, Boolean isStore) {
        TradeOrderStatusEnum nowStatus = TradeOrderStatusEnum.getEnum(order.getStatus());

        switch (nowStatus) {
            case UNPAID -> {
                if (DeliveryTypeEnum.PICK_UP.getType().equals(order.getDeliveryType())) {
                    return TradeOrderStatusEnum.UNPICK_MEMBER;
                }
                return TradeOrderStatusEnum.UNDELIVERED_MEMBER;
            }
            // 待上门 --(验金)--> 验金完成 --(创建结算单)--> 待确认 --(支付成功)--> 已结算
            case CHECK_DONE -> {
                return TradeOrderStatusEnum.WAIT_CONFIRM;
            }
            case WAIT_CONFIRM, SETTLING, WAIT_PAY_CHECK -> {
                if (isStore) {
                    return TradeOrderStatusEnum.COMPLETED;
                }
                if (DeliveryTypeEnum.PICK_UP.getType().equals(order.getDeliveryType())) {
                    return TradeOrderStatusEnum.COMPLETED;
                }
                return TradeOrderStatusEnum.PREPARE;
            }
            case PREPARE -> {
                return TradeOrderStatusEnum.DELIVERED;
            }
            case DELIVERED -> {
                return TradeOrderStatusEnum.COMPLETED;
            }

        }
        return null;
    }

} 